﻿using System.Collections;
using QFramework;
using UnityEditor;
using UnityEngine;

namespace Gp.Scripts.Core {
    public class UnitModel : MonoBehaviour {
        public BaseUnit UnitReference { get; private set; }
        public Animator Animator { get; private set; }

        public bool IsInit { get; private set; } = false;


        public UnitOutlineRenderer OutlineRenderer { get; private set; }
        
        /// <summary>
        /// 当前正在执行的动画序列
        /// </summary>
        public UnitGestureSequence CurrentPlayingGestureSequence { get; private set; }

        protected virtual void Awake() {
            // 动画事件组件
            var animationEvent = this.GetOrAddComponent<UnitAnimatorEventTrigger>();
            animationEvent.OnEventTrigger += OnAnimationEvent;
        }

        
        public void Init(BaseUnit unit) {
            if (IsInit) return;
            IsInit = true;
            UnitReference = unit;
            Animator = GetComponentInChildren<Animator>();
            Animator.enabled = true;
            
            var col = GetComponent<Collider>();
            if (col != null && col.gameObject != unit.gameObject)
            {
                col.enabled = false;
            }
            
            InitHighlighter();
            
            // 子类初始化逻辑
            OnInit();
        }
        
        
        protected void InitHighlighter()
        {
            this.OutlineRenderer = new UnitOutlineRenderer(this);
            OutlineRenderer.SetOutlineMode(UnitOutlineMode.Normal);
        }
        
        
        protected virtual void OnInit() { }
        
        
        public void TriggerAnimationEvent(string eventName) {
            OnAnimationEvent(eventName);
        }
        protected virtual void OnAnimationEvent(string eventName) {
            CurrentPlayingGestureSequence?.OnAnimationEvent(eventName);
        }


        public void GestureTrigger<T>() where T : UnitGestureTrigger, new() {
            GestureTrigger(new T());
        }


        public void GestureTrigger<T>(T gestureTrigger) where T : UnitGestureTrigger {
            if (CurrentPlayingGestureSequence != null) return;
            gestureTrigger.Init(this);
            gestureTrigger.OnTrigger();
        }
        
        public void MarkAs<T>(T state) where T : UnitModelStateMark {
            state.Init(this);
            state.OnMark();
        }

        public UnitModelStateMark MarkAs<T>() where T : UnitModelStateMark, new() {
            var mark = new T();
            MarkAs(mark);
            return mark;
        }


        public IEnumerator PlaySequence<T>(T gesture) where T : UnitGestureSequence {
            gesture.Init(this);
            CurrentPlayingGestureSequence = gesture;
            yield return gesture.PlayGestureSequence();
            CurrentPlayingGestureSequence = null;
        }

        public IEnumerator PlaySequence<T>() where T : UnitGestureSequence, new() {
            T gesture = new T();
            yield return PlaySequence(gesture);
        }
        

        public void ForwardToTarget(Vector3 targetPos) {
            var dir =  targetPos - UnitReference.transform.position;
            dir.y = 0;
            UnitReference.transform.rotation = Quaternion.LookRotation(dir);
        }
    }
}